package com.motu.monstercity.server.game.web;

import com.motu.monstercity.module.common.iap.Iap;
import com.motu.monstercity.module.common.iap.IapGift;
import com.motu.monstercity.module.common.utility.EventBusConstant;
import com.motu.monstercity.server.game.logic.IapManager;
import com.motu.monstercity.server.game.verticle.MainVerticle;
import com.motu.vertx.module.utility.main.MainService;
import com.motu.vertx.module.utility.mysql.MysqlClient;
import com.motu.vertx.module.utility.mysql.MysqlTool;
import com.motu.vertx.module.utility.toolset.ErrorWord;
import com.motu.vertx.module.utility.toolset.TimeUtils;
import com.motu.vertx.module.utility.webtool.BaseWebHandler;
import io.vertx.core.CompositeFuture;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.client.WebClient;
import io.vertx.sqlclient.Pool;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;

public class ChargemissHandler extends BaseWebHandler {

    public static final String tableName1 = "iap_order";

    /***
     * 校验userid是否存在
     * @return 异步查询结果
     */
    public static Future<JsonObject> checkUserid(long userid){
        Promise<JsonObject> fut = Promise.promise();
        String sql = "select * FROM user_info where id = ?;";
        JsonArray params = new JsonArray();
        params.add(userid);
        MysqlTool.queryJsonArrayFromDb(MysqlClient.getGamePool(), sql, params, handler->{
            if(handler.succeeded()){
                JsonArray list = handler.result();
                if(list.size() == 1){
                    JsonObject obj = list.getJsonObject(0);
                    JsonObject result = new JsonObject();
                    result.put("userinfo",obj);
                    fut.complete(result);
                }else{
                    fut.fail("数据查询为空");
                }
            }else{
                fut.fail(handler.cause().getMessage());
            }
        });
        return fut.future();
    }

    /*
     * 补单
     */
    public static void addorder(RoutingContext routingContext, JsonObject json, String adminName, WebClient client) {
        Pool jdbcClient = MysqlClient.getGamePool();
        JsonObject data = json.getJsonObject("data");
        MainVerticle.logger.info("data:" + data.toString());
        Future<JsonObject> checkUseridResult = checkUserid(data.getLong("user_id"));
        checkUseridResult.onComplete(checkHandler -> {
            if(checkHandler.failed()){
                sendHttpResponseError(routingContext.response(), "check userid error !!!!");
            } else {
                int iapGiftId = data.getInteger("iap_gift_id");
                IapGift iapGift = IapManager.getIapGift(iapGiftId);
                if (iapGift.getIapId() == 0) {   //非免费充值项
                    sendHttpResponseError(routingContext.response(), "免费项不允许补单!!!");
                    return;
                }
//                data.remove("iap_gift_id");
//                data.put("iap_gift_id", iapGiftId);
                Iap iap = IapManager.getIap(iapGift.getIapId());
                data.put("money", iap.getBiMoney());
                data.put("product_id", "");

                int isFake = data.getInteger("is_fake");            //1虚拟补单，0补单
//                data.remove("is_fake");
//                data.put("is_fake", isFake);

                boolean isSuffix = true;//订单后缀处理
                //如果 数量为1 订单号有填写，则不做后缀处理
                if (data.getInteger("num") == 1 && data.containsKey("order_id")) {
                    isSuffix = false;
                }
                if (!data.containsKey("order_id")) {
                    data.put("order_id", data.getLong("user_id") + "_" + System.currentTimeMillis());
//                } else {
//                    String orderId = data.getString("order_id");
//                    data.remove("order_id");
//                    data.put("order_id", orderId);
                }
                data.put("add_time", TimeUtils.getCurTime());
                data.put("diamond", iapGift.getDiamond());

                int num = data.getInteger("num");
                String orderId = data.getString("order_id");
                data.remove("num");//num字段不插入到数据库
                List<Future> futures = new ArrayList<>();
                MainVerticle.logger.info("change data:" + data.toString());
                for (int i = 0; i < num; i++) {
                    JsonObject data2 = data.copy();
                    if(isSuffix) {//orderid再拼接一个后缀
                        data2.put("order_id", orderId+"_"+i);
                    }
                    futures.add(addToIapOrder(routingContext, json, jdbcClient, tableName1, data2, adminName));
                }
                boolean finalIsSuffix = isSuffix;
                CompositeFuture.all(futures).onComplete(handler -> {
                    int count = 0;
                    for (int i = 0; i < num; i++) {
                        int ret = (Integer) futures.get(i).result();
                        if (ret == 0) {
                            count++;
                        }
                    }
                    if (count > 0) {
                        String oId = orderId;
                        if(finalIsSuffix ) {//orderid再拼接一个后缀
                            oId += "_";
                            if (count == 1) {
                                oId += "0";
                            }
                        }
//                        String oId = orderId + "_";
//                        if (count == 1) {
//                            oId += "0";
//                        }
                        noticeGameReceiveIap(data.getLong("user_id"), oId, iapGiftId, isFake, 0, count);
                        //记录操作者日记
                        String reason = "";
                        if (json.containsKey("reason")) {
                            reason = json.getString("reason");
                        }
                        String operation = "";
                        if (isFake == 1) {        //虚拟补单
                            operation = "【虚拟补单】";
                        } else {
                            operation = "【补单】";
                        }
                        operation += iap.getMoney() + "元" + " iapGiftId:" + iapGiftId + "(" + count + "笔)";        //操作详情
                        addGameUserLog(MysqlClient.getServerPool(), data.getLong("user_id"), adminName, reason, operation);
                    }
                    sendHttpResponse(routingContext.response(), new JsonObject().put("num", count));
                });
            }
        });

    }

    private static Future<Integer> addToIapOrder(RoutingContext routingContext, JsonObject json, Pool jdbcClient, String tableName, JsonObject jsonDecrypt, String adminName) {
        Promise<Integer> fut = Promise.promise();
        JsonObject json2 = jsonDecrypt != null ? jsonDecrypt : json;
        Iterator<Entry<String, Object>> it = json2.iterator();
        JsonArray params = new JsonArray();
        String keys = "";
        String values = "";
        while (it.hasNext()) {
            Entry<String, Object> en = it.next();
            keys += en.getKey();
            values += "?";
            if (it.hasNext()) {
                keys += ",";
                values += ",";
            }
            if (en.getValue() == null) {
                MainVerticle.logger.error("addToIapOrder null key :" + en.getKey());
            } else {
                params.add(en.getValue());
            }
        }

        String sql = "insert into " + tableName + "(" + keys + ") values(" + values + "); ";
        MainVerticle.logger.info("addToIapOrder sql:" + sql + " params:" + params);
        int isFake = json2.getInteger("is_fake");
        MysqlTool.insertAndGetID(jdbcClient, sql, params, handler -> {
            if (handler.succeeded()) {
                Long res = handler.result();//只返回插入后的自增值而已
                JsonObject result = new JsonObject();
                if (res != null) {//如果有自增值再取
                    long id = res.longValue();
                    result.put("id", id);
                }
                fut.complete(0);
            } else {
                MainVerticle.logger.error(handler.cause().getMessage());
                fut.complete(ErrorWord.MYSQL_INSERT_FAILED.value);
            }
        });
        return fut.future();
    }

    /*
     * 通知游戏服收到充值回调并已入库到iaporder
     */
    private static void noticeGameReceiveIap(long userId, String orderId, int iapGiftId, int isFake, int offline, int count) {
        JsonObject message = new JsonObject();
        message.put("user_id", userId);
        JsonObject obj = new JsonObject();
        obj.put("order_id", orderId);
        obj.put("iap_gift_id", iapGiftId);
        obj.put("is_fake", isFake);
        obj.put("offline", offline);
        obj.put("count", count);// 充值几笔
        message.put("obj", obj);
        String ebName = EventBusConstant.getAddress(EventBusConstant.GAME_IAP);
        EventBus eventBus = MainService.getVertx().eventBus();
        eventBus.request(ebName, message, ar -> {
            if (ar.succeeded()) {
                JsonObject recData = (JsonObject) ar.result().body();
                if (recData.containsKey("retry")) {
                    noticeGameReceiveIap(userId, orderId, iapGiftId, isFake, offline, count);//递归重发
                    MainVerticle.logger.info("-------!!!!!!!------- retry  noticeGameReceiveIap userId:" + userId + " orderId:" + orderId + " iapGiftId:" + iapGiftId);
                } else {
                    //处理成功
                }
            } else {
                MainVerticle.logger.error("eventBus.send failed:" + ar.cause().getMessage());
            }
        });
    }

//    /*
//     * 线下充值
//     */
//    public static void chargeOffline(RoutingContext routingContext, JsonObject json, String adminName, WebClient client) {
//        Pool jdbcClient = MysqlClient.getGamePool();
//        JsonObject data = json.getJsonObject("data");
//        int iapGiftId = data.getInteger("iap_gift_id");
//        int num = data.getInteger("num");                //充值条数
//        IapGift iapGift = GameDataManager.getIapGift(iapGiftId);
//        Iap iap = GameDataManager.getIap(iapGift.getIapId());
//        double money = iap.getBiMoney();        //充值金额
//        long diamond = iapGift.getDiamond();    //钻石
//        String productId = "";
//
//        List<Future> futlist = new ArrayList<>();   //设置插入任务队列
//        for (int i = 0; i < num; i++) {
//            Future<Integer> fut = Future.future();
//            futlist.add(fut);
//        }
//
//        String sql = "insert into iap_order (user_id, platform, iap_gift_id, money, diamond, product_id, order_id, trans_info, add_time, offline) values (?,?,?,?,?,?,?,?,?,?);";
//        int curTime = Tool.getCurTime();
//        for (int i = 0; i < num; i++) {
//            JsonArray params = new JsonArray();
//            params.add(data.getLong("user_id"));
//            params.add(data.getInteger("platform"));
//            params.add(iapGiftId);
//            params.add(money);
//            params.add(diamond);
//            params.add(productId);
//            String orderId = "offline_" + data.getLong("user_id") + "_" + curTime + "_" + i;
//            params.add(orderId);
//            params.add(data.getString("trans_info"));
//            params.add(curTime);
//            params.add(1);
//            MainVerticle.logger.info("addToIapOrder offline:" + Tool.getSqlString(sql, params));
//            int index = i;
//            MysqlTool.insertAndGetID(jdbcClient, sql, params, handler -> {
//                if (handler.succeeded()) {
//                    futlist.get(index).complete(0);
//                } else {
//                    MainVerticle.logger.error(handler.cause().getMessage());
//                    futlist.get(index).complete(-1);
//                }
//            });
//        }
//
//        CompositeFuture.all(futlist).setHandler(handler -> {
//            int count = 0;  //充值成功条数
//            for (int i = 0; i < num; i++) {
//                int ret = (Integer) futlist.get(i).result();
//                if (ret == 0) {
//                    count++;
//                }
//            }
//            if (count > 0) {
//                String orderId = "offline_" + data.getLong("user_id") + "_" + curTime + "_";
//                if (count == 1) {
//                    orderId += "0";
//                }
//                noticeGameReceiveIap(data.getLong("user_id"), orderId, iapGiftId, 0, 1, count);
//            }
//            String res_str = json.getString("money");
//            String ope_str = "【线下充值】" + iap.getId() + "(" + count + "笔)";
//            addGameUserLog(MysqlClient.getServerPool(), data.getLong("user_id"), adminName, res_str, ope_str);
//            sendHttpResponse(routingContext.response(), new JsonObject().put("num", count));
//        });
//    }
}
